import { getConfig } from '@libs/common/utils';
import { Inject, Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { Dayjs } from '@shencom/utils-date';
import ms from 'ms';

import { DingdingService } from '@/dingding/dingding.service';
import { MemberService } from '@/dingding/member/member.service';
import { SysUserService } from '@/user/sys-user/sys-user.service';

const { JWT } = getConfig();

interface DingUser {
  avatar?: string;
  dingId: string;
  phone: string;
  deptIdList: string;
  position: string;
  deptNameList: string;
}
export interface SysUser extends DingUser, SC.User.SysInfo {}
@Injectable()
export class AuthService {
  @Inject(DingdingService) private readonly dingdingService: DingdingService;

  @Inject(MemberService) private readonly memberService: MemberService;

  @Inject(SysUserService) private readonly sysUserService: SysUserService;

  @Inject(JwtService) private readonly jwtService: JwtService;

  async login(code: string) {
    const dingUserInfo = await this.dingdingService.getUserInfo(code);

    const { userid: dingId } = dingUserInfo;

    if (!dingId) throw new Error('用户不存在');

    const member = await this.memberService.findOne({ dingUserId: dingId });

    if (!member?.userId) throw new Error('用户不存在');

    if (member?.status === 0) throw new Error('用户已禁用');

    const sysUser = await this.sysUserService.userInfo(member.userId);

    const user = {
      ...sysUser,
      avatar: member.avatar,
      dingId: member.dingUserId,
      phone: member.phone,
      realname: member.name,
      deptIdList: member.deptIdList,
      position: member.position,
      deptNameList: member.deptNameList,
    };
    const rootUser = await this.sign(user);

    return rootUser;
  }

  async sign(user: SysUser) {
    const accessToken = await this.jwtService.signAsync(user, {
      expiresIn: JWT.access_token_expires_time,
    });

    const refreshToken = await this.jwtService.signAsync(user, {
      expiresIn: JWT.refresh_token_expires_time,
    });

    const token = {
      refreshToken: {
        expiration: Dayjs().valueOf() + ms(JWT.refresh_token_expires_time),
        value: refreshToken,
      },
      value: accessToken,
      expiration: Dayjs().valueOf() + ms(JWT.access_token_expires_time),
    };

    const rootUser = {
      additionalInformation: user,
      ...token,
    };

    return rootUser as SC.User.RootInfo;
  }
}
